package db

import (
	"context"
	"ip_server/logger"
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

type DBConfig struct {
	DatabaseName string
	User         string
	Password     string
	Host         string
	Port         int
	Charset      string
	Timezone     string
}

var (
	DatabaseName string
	User         string
	Password     string
	Host         string
	Port         int
	Charset      string
	Timezone     = "+08:00"
)

type DBWrapper struct {
	*sql.DB
}

var (
	DbWrapper *DBWrapper
)

func SetConfig(config DBConfig) {
	DatabaseName = config.DatabaseName
	User = config.User
	Password = config.Password
	Host = config.Host
	Port = config.Port
	Charset = config.Charset
	Timezone = config.Timezone
}

func OpenDB() error {
	var err error
	// dataSourceName := "user:password@tcp(127.0.0.1:3306)/dbname"
	dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v", User, Password, Host, Port, DatabaseName)
	DbWrapper, err = NewDBWrapper(dataSourceName)
	if err != nil {
		logger.NewLogger().Error("数据库连接失败:", err)
		return err
	}
	return nil
}

func NewDBWrapper(dataSourceName string) (*DBWrapper, error) {
	db, err := sql.Open("mysql", dataSourceName)
	if err != nil {
		logger.NewLogger().Error(err)
		return nil, err
	}
	err = db.Ping()
	if err != nil {
		logger.NewLogger().Error(err)
		return nil, err
	}
	return &DBWrapper{db}, nil
}

func (db *DBWrapper) Close() error {
	logger.Info("sql close")
	return db.DB.Close()
}

// 预编译后进行查询
func (db *DBWrapper) PrepareToQuery(query string, args ...interface{}) (*sql.Rows, error) {
	logger.Info("sql Query:%v, params:", query, args)
	// 这里可以添加额外的逻辑，例如日志记录、参数校验等
	stmt, err := db.Prepare(query)
	if err != nil {
		logger.NewLogger().Error(err)
		return nil, err
	}
	rows, err := stmt.Query(args...)
	if err != nil {
		logger.NewLogger().Error(err)
		return nil, err
	}
	return rows, nil
}

func (db *DBWrapper) QueryRow(query string, args ...interface{}) *sql.Row {
	logger.Info("sql Query:%v, params:", query, args)
	return db.DB.QueryRowContext(context.Background(), query, args...)
}

// 没有进行预编译，直接进行查询
func (db *DBWrapper) Query(query string, args ...interface{}) (*sql.Rows, error) {
	logger.Info("sql Query:%v, params:", query, args)

	rows, err := db.DB.Query(query, args...)
	if err != nil {
		logger.NewLogger().Error(err)
		return nil, err
	}
	return rows, nil
}

func (db *DBWrapper) Exec(query string, args ...interface{}) error {
	logger.Info("sql exec:%v, params:", query, args)
	// 这里可以添加额外的逻辑，例如日志记录、参数校验等
	stmt, err := db.Prepare(query)
	if err != nil {
		logger.NewLogger().Error("Prepare",err)
		return err
	}
	result, err := stmt.Exec(args...)
	if err != nil {
		logger.NewLogger().Error(err)
		return err
	}
	rowsAffected, err := result.RowsAffected()
	if err != nil {
		logger.NewLogger().Error(err)
		return err
	}
	logger.Info("affect number of affected is :%v", rowsAffected)

	return nil
}
